package top.yangguangmc.sunshine_anticheat.check.checks.player;

import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import top.yangguangmc.sunshine_anticheat.check.Check;
import top.yangguangmc.sunshine_anticheat.check.CheckCategory;
import top.yangguangmc.sunshine_anticheat.check.CheckSetting;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AutoRespawnCheck extends Check {
    private final Map<Player, Long> playerDeathTimes = new HashMap<>();

    @CheckSetting(configName = "threshold")
    private int thresholdMS = 1050;
    @CheckSetting(configName = "worlds")
    private List<String> worlds = new ArrayList<>();
    @CheckSetting(configName = "is-whitelist")
    private boolean isWhitelist = false;

    public AutoRespawnCheck() {
        super("AutoRespawn", "auto-respawn", CheckCategory.PLAYER);
    }

    @EventHandler
    public void onPlayerDeath(PlayerDeathEvent event) {
        if (validateCheckable(event.getEntity())) {
            playerDeathTimes.put(event.getEntity(), System.currentTimeMillis());
        }
    }

    @EventHandler
    public void onPlayerRespawn(PlayerRespawnEvent event) {
        if (validateCheckable(event.getPlayer())) {
            Player player = event.getPlayer();
            Long lastDeath = playerDeathTimes.get(player);
            if (lastDeath != null) {
                for (String worldName : worlds) {
                    if (isWhitelist) {
                        if (!player.getWorld().getName().equals(worldName)) return;
                    } else {
                        if (player.getWorld().getName().equals(worldName)) return;
                    }
                }
                long respawnTime = System.currentTimeMillis() - lastDeath;
                if (respawnTime < thresholdMS) {
                    int vlAddition;
                    if (respawnTime < thresholdMS * (1.0 / 4.0)) {
                        vlAddition = 5;
                    } else if (respawnTime < thresholdMS * (1.0 / 2.0)) {
                        vlAddition = 3;
                    } else vlAddition = 1;
                    failCheck(player, vlAddition, "Respawned" + (vlAddition == 5 ? " much" : "")
                            + " too quickly (In " + respawnTime + "ms).");
                    playerDeathTimes.remove(player);
                }
            }
        }
    }

}
